package payment.mobilepos.unionpay.com.metroguide.ui;

import android.content.Context;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.SingleTransformer;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Function;
import payment.mobilepos.unionpay.com.metroguide.api.Api;
import payment.mobilepos.unionpay.com.metroguide.app.MyApplication;
import payment.mobilepos.unionpay.com.metroguide.bean.QueryFare;
import payment.mobilepos.unionpay.com.metroguide.bean.QueryPath;
import payment.mobilepos.unionpay.com.metroguide.utils.JsonParser;
import payment.mobilepos.unionpay.com.metroguide.utils.StringUtils;

import static payment.mobilepos.unionpay.com.metroguide.api.HostType.GANK_GIRL_PHOTO;
import static payment.mobilepos.unionpay.com.metroguide.api.HostType.NETEASE_NEWS_VIDEO;

/**
 * <pre>
 *     author : liuso
 *     e-mail : xxx@xx
 *     time   : 2018/12/24
 *     desc   :
 *     version: 1.0
 * </pre>
 */
public class MainModel implements MainContract.Model {
    public Observable<List<String>> getAllStations() {
        return Api.getDefault(GANK_GIRL_PHOTO)
                .getAllStations("getAllStations")
                .flatMap(new Function<List<Stations>, ObservableSource<Stations>>() {
                    @Override
                    public ObservableSource<Stations> apply(List<Stations> stations) throws Exception {
                        return Observable.fromIterable(stations);
                    }
                }).map(new Function<Stations, String>() {
                    @Override
                    public String apply(Stations stations) throws Exception {
                        return stations.getKey();
                    }
                }).reduceWith(new Callable<List<String>>() {
                    @Override
                    public List<String> call() throws Exception {
                        return new ArrayList<>();
                    }
                }, new BiFunction<List<String>, String, List<String>>() {
                    @Override
                    public List<String> apply(List<String> list, String s) throws Exception {
                        list.add(s);
                        return list;
                    }
                }).compose(new SingleTransformer<List<String>, List<String>>() {
                    @Override
                    public SingleSource<List<String>> apply(Single<List<String>> upstream) {
                        return null;
                    }
                })
                .toObservable()
                .compose(RxSchedulers.<List<String>>io_main());
    }

    @Override
    public Observable<QueryFare> queryFare(String startStationKey, String endStationsKey, String type) {
        return Api.getDefault(NETEASE_NEWS_VIDEO)
                .queryFare(startStationKey, endStationsKey, "0")
                .compose(RxSchedulers.<QueryFare>io_main());
    }

    @Override
    public Observable<Object> queryPath(String startStationKey, String endStationsKey, String type, final Context context) {
        return Api.getDefault(NETEASE_NEWS_VIDEO)
                .queryPath(startStationKey, endStationsKey, "0")
                .flatMap(new Function<QueryPath, Observable<String>>() {
                    @Override
                    public Observable<String> apply(QueryPath queryPath) throws Exception {
                        return Observable.fromArray(queryPath.getData().getList().get(0).getPsid().split("-"));
                    }
                })
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String s) throws Exception {
                        Map<String, String> json = JsonParser.getJson(MyApplication.getAppContext(), true);
                        return json.get(StringUtils.addZeroForNum(s, 4));
                    }
                })
                .distinct()
                .collect(new Callable<StringBuilder>() {
                    @Override
                    public StringBuilder call() throws Exception {
                        return new StringBuilder();
                    }
                }, new BiConsumer<StringBuilder, String>() {
                    @Override
                    public void accept(StringBuilder builder, String s) throws Exception {
                        builder.append(s + "-");
                    }
                })
                .map(new Function<StringBuilder, String>() {
                    @Override
                    public String apply(StringBuilder stringBuilder) throws Exception {
                        String s = stringBuilder.toString();
                        return s.length() != 0 ? s.substring(0, s.length() - 1) : "";
                    }
                })
                .toObservable()
                .compose(RxSchedulers.io_main());


    }
}